package com.lyf.boot.modules.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyf.boot.base.system.entity.SysRole;
import com.lyf.boot.base.system.entity.SysRolePerm;
import com.lyf.boot.core.model.OptionVo;
import com.lyf.boot.core.model.PageInfo;
import com.lyf.boot.modules.system.dao.SysRoleDao;
import com.lyf.boot.modules.system.dao.SysRolePermDao;
import com.lyf.boot.modules.system.entity.dto.SysRoleDto;
import com.lyf.boot.modules.system.entity.dto.SysRolePageDto;
import com.lyf.boot.modules.system.entity.dto.SysRolePermDto;
import com.lyf.boot.modules.system.entity.vo.SysRoleVo;
import com.lyf.boot.modules.system.service.ISysRoleService;
import com.lyf.boot.utils.MapstructUtil;
import com.lyf.boot.utils.StreamUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Luyufan
 * @date 2023/7/7 15:36
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl implements ISysRoleService {

    private final SysRoleDao sysRoleDao;

    private final SysRolePermDao sysRolePermDao;

    @Override
    public PageInfo<SysRoleVo> getSysRolePage(SysRolePageDto dto) {
        Page<SysRoleVo> page = dto.of();
        return PageInfo.build(sysRoleDao.selectSysRolePage(page, dto));
    }

    @Override
    public List<OptionVo> getAllRole() {
        return sysRoleDao.selectAllRole();
    }

    @Override
    public SysRoleVo getSysRoleInfo(Long roleId) {
        SysRoleVo sysRoleVo = sysRoleDao.selectSysRoleById(roleId);
        Assert.notNull(sysRoleVo, "角色不存在");
        List<SysRolePerm> rolePerms = sysRolePermDao.selectList(Wrappers.<SysRolePerm>lambdaQuery().eq(SysRolePerm::getRoleId, roleId));
        if(CollUtil.isNotEmpty(rolePerms)){
            sysRoleVo.setPermIds(StreamUtil.toList(rolePerms, SysRolePerm::getPermId));
        }
        return sysRoleVo;
    }

    @Override
    public void saveSysRole(SysRoleDto dto) {
        String roleCode = dto.getRoleCode();
        Assert.state(!sysRoleDao.exists(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, roleCode)),"角色编码[{}]已存在", roleCode);
        SysRole sysRole = MapstructUtil.convert(dto, SysRole.class);
        sysRoleDao.insert(sysRole);
    }

    @Override
    public void updateSysRole(SysRoleDto dto) {
        Long roleId = dto.getRoleId();
        SysRole sysRoleDb = sysRoleDao.selectById(roleId);
        Assert.notNull(sysRoleDb, "角色不存在");
        if(!StrUtil.equals(sysRoleDb.getRoleCode(), dto.getRoleCode())){
            String roleCode = dto.getRoleCode();
            Assert.state(!sysRoleDao.exists(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, roleCode)),"角色编码[{}]已存在", roleCode);
        }
        SysRole sysRole = MapstructUtil.convert(dto, SysRole.class);
        sysRoleDao.updateById(sysRole);

    }

    @Override
    public void deleteSysRole(List<Long> ids) {
        sysRoleDao.deleteByIds(ids);
    }

    @Override
    public List<Long> getSysRolePermList(Long roleId) {
        return sysRolePermDao.selectList(Wrappers.<SysRolePerm>lambdaQuery()
                .eq(SysRolePerm::getRoleId, roleId))
                .stream().map(SysRolePerm::getPermId)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void grantRolePerm(SysRolePermDto dto) {
        Long roleId = dto.getRoleId();
        sysRolePermDao.delete(Wrappers.<SysRolePerm>lambdaQuery().eq(SysRolePerm::getRoleId, roleId));
        if(CollUtil.isNotEmpty(dto.getPermIds())){
            List<SysRolePerm> rolePerms = new ArrayList<>();
            dto.getPermIds().forEach(menuId -> rolePerms.add(new SysRolePerm(roleId, menuId)));
            sysRolePermDao.insertBatchSomeColumn(rolePerms);
        }
    }
}
